package org.vectrics.recruiter.reporting;

import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Iterator;
import java.util.Locale;
import java.util.TreeMap;
import java.util.TreeSet;

import org.apache.log4j.Logger;
import org.vectrics.SystemException;
import org.vectrics.VectricsException;
import org.vectrics.common.db.DataUtils;
import org.vectrics.common.reporting.pdf.ReportUtil;
import org.vectrics.common.util.DateUtil;
import org.vectrics.company.Company;
import org.vectrics.domain.Domain;
import org.vectrics.history.Activity;
import org.vectrics.history.HistoryProvider;
import org.vectrics.location.Address;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.recruiter.RecruitServiceLocator;
import org.vectrics.recruiter.config.RecruitConfig;
import org.vectrics.recruiter.job.Job;
import org.vectrics.recruiter.job.JobCandidate;
import org.vectrics.recruiter.job.JobSkillRatingSet;
import org.vectrics.recruiter.job.JobStatus;
import org.vectrics.recruiter.job.JobStatusDateComparator;
import org.vectrics.recruiter.user.CandidateInfo;
import org.vectrics.recruiter.user.Interview;
import org.vectrics.skill.Skill;
import org.vectrics.skill.SkillRatingSet;
import org.vectrics.struts.PhraseManager;
import org.vectrics.user.Person;

import com.lowagie.text.Chapter;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Phrase;
import com.lowagie.text.Section;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;

public class JobReport extends RecruitBaseReport {
    private transient static Logger log = Logger.getLogger(JobReport.class);

    private Long jobId = null;

    private SimpleDateFormat historyDateFormat = new SimpleDateFormat("dd/MM/yyyy");

    private Job job = null;

    private boolean showInterviews = true;

    // private boolean showCompleteHistory = false;
    private boolean showStatusHistory = true;

    public JobReport(final Domain domain, final Locale locale) {
        super(domain, locale);
    }

    private Job getJob() {
        if (job == null) {
            if (jobId == null) {
                log.error("JobReport needs jobId assigned before calling build() method");
                throw new SystemException("JobReport needs jobId assigned before calling build() method");
            }

            job = RecruitServiceLocator.getJobProvider().findJob(jobId);
            if (job == null) {
                log.error("JobReport was assigned a jobId which could not be found: " + jobId);
                throw new SystemException("JobReport was assigned a jobId which could not be found: " + jobId);
            }
        }
        return job;
    }

    private void addInfoRow(final PdfPTable infoTable, final String captionCode, final String value) {
        String caption = CoreServiceLocator.getPhraseProvider().getMessage(captionCode, getLocale());
        PdfPCell captionCell = new PdfPCell(new Phrase(caption, ReportConstants.stdBoldFont));
        captionCell.setBorderWidth(0);
        infoTable.addCell(captionCell);
        String valueStr = value;
        if (valueStr == null || valueStr.length() <= 0) {
            valueStr = PhraseManager.getNotGiven(getLocale());
        }
        PdfPCell valueCell = new PdfPCell(new Phrase(valueStr, ReportConstants.stdFont));
        valueCell.setBorderWidth(0);
        infoTable.addCell(valueCell);

        PdfPCell blankCell = new PdfPCell(new Phrase(" ", ReportConstants.stdFont));
        blankCell.setBorderWidth(0);
        infoTable.addCell(blankCell);
    }

    private void addCoreRow(final PdfPTable coreTable, final String captionCode, final String value) {
        String caption = CoreServiceLocator.getPhraseProvider().getMessage(captionCode, getLocale());
        PdfPCell captionCell = new PdfPCell(new Phrase(caption, ReportConstants.stdBoldFont));
        captionCell.setBorderWidth(1);
        coreTable.addCell(captionCell);
        String valueStr = value;
        if (valueStr == null || valueStr.length() <= 0) {
            valueStr = getPhrase("phrase.not.given");
        }
        PdfPCell valueCell = new PdfPCell(new Phrase(valueStr, ReportConstants.stdFont));
        valueCell.setBorderWidth(1);
        valueCell.setPaddingBottom(5);
        coreTable.addCell(valueCell);
    }

    protected String getCompanyName(final Job job) {
        String name = "";
        if (job != null) {
            Company company = job.getCompany();
            if (company != null) {
                name = company.getName();
            }
        }
        return name;
    }

    @Override
    protected void fill(final Document document) throws VectricsException {
        log.debug("Job Report - building");

        Job job = getJob();
        try {
            document.add(new Paragraph(" ", ReportConstants.heading1Font));
            document.add(new Paragraph(" ", ReportConstants.heading1Font));
            document.add(new Paragraph(" ", ReportConstants.heading1Font));
            document.add(new Paragraph("Job Order Details Report", ReportConstants.heading1Font));
            document.add(new Paragraph(" ", ReportConstants.heading1Font));
            document.add(new Paragraph(job.getTitle(), ReportConstants.heading3Font));
            document.add(new Paragraph(job.getReferenceId(), ReportConstants.heading3Font));
            Chapter chapter1 = createChapter("Job Order Information");
            PdfPTable coreTable = new PdfPTable(2);
            coreTable.setHorizontalAlignment(Element.ALIGN_LEFT);
            coreTable.setWidthPercentage(80);
            int coreTableWidths[] = { 200, 300 };
            coreTable.setWidths(coreTableWidths);

            if (RecruitConfig.getRecruitInstance().getAllowMultipleCompanies(getDomain())) {
                addCoreRow(coreTable, "prompt.job.company", getCompanyName(job));
            }

            addCoreRow(coreTable, "prompt.job.title", job.getTitle());
            addCoreRow(coreTable, "prompt.job.reference.id", job.getReferenceId());
            if (job.getDatePosted() != null) {
                addCoreRow(coreTable, "prompt.job.date.posted", historyDateFormat.format(job.getDatePosted()));
            } else {
                addCoreRow(coreTable, "prompt.job.date.posted", " ");
            }

            addCoreRow(coreTable, "prompt.job.function", job.getFunctionDescription());
            if (job.getHiringManager() == null) {
                addCoreRow(coreTable, "prompt.job.hiring.manager", null);
            } else {
                addCoreRow(coreTable, "prompt.job.hiring.manager", job.getHiringManager().getName());
            }

            log.debug("Showing location...");
            addCoreRow(coreTable, "prompt.job.location", job.getLocationDescription());
            log.debug("Showing work schedule...");
            addCoreRow(coreTable, "prompt.job.work.schedule", job.getWorkScheduleDescription());
            addCoreRow(coreTable, "prompt.job.terms", job.getTermDescription());

            if (job.getSalary() != null) {
                NumberFormat numFormat = NumberFormat.getCurrencyInstance(Locale.US);
                addCoreRow(coreTable, "prompt.job.salary", numFormat.format(job.getSalary().doubleValue()));
            } else {
                addCoreRow(coreTable, "prompt.job.salary", null);
            }
            addCoreRow(coreTable, "prompt.job.terms", job.getTermDescription());
            Person recruiter = job.getPrimaryRecruiter();
            if (recruiter != null) {
                addCoreRow(coreTable, "prompt.job.primary.recruiter", recruiter.getName());
            }
            recruiter = job.getSecondaryRecruiter();
            if (recruiter != null) {
                addCoreRow(coreTable, "prompt.job.secondary.recruiter", recruiter.getName());
            }

            chapter1.add(coreTable);
            chapter1.add(new Paragraph(" "));
            document.add(chapter1);

            PdfPTable infoTable = new PdfPTable(1);
            infoTable.setHorizontalAlignment(Element.ALIGN_LEFT);
            infoTable.setWidthPercentage(60);
            int infoTableWidths[] = { 200 };
            infoTable.setWidths(infoTableWidths);

            addInfoRow(infoTable, "phrase.job.description", job.getDescription());
            addInfoRow(infoTable, "prompt.job.company.information", job.getCompanyInfo());
            addInfoRow(infoTable, "phrase.skills.required", job.getRequiredSkills());
            addInfoRow(infoTable, "prompt.job.education", job.getEducation());
            addInfoRow(infoTable, "prompt.job.search.words", job.getSearchWords());

            document.add(infoTable);

            document.add(new Paragraph(" "));

            Chapter chapter = createChapter("Candidates");
            chapter.add(makeCandidateTable(job));
            document.add(chapter);

            if (showStatusHistory == true) {
                chapter = createChapter("Status History");
                makeStatusHistorySection(chapter);
                document.add(chapter);
            }

            if (showInterviews == true) {
                chapter = createChapter("Candidate Interviews");
                makeInterviewSection(chapter);
                document.add(chapter);
            }

            JobSkillRatingSet ratingSet = RecruitServiceLocator.getSkillProvider().findJobSkillSet(job);

            // document.add(new Paragraph(" "));

            /*
             * if (ratingSet.findAllSkillRatings().size() > 0) {
             * document.add(makeSkillsTable(ratingSet, job)); } else {
             * log.debug("job has no skills, not showing skills section"); }
             * 
             * document.add(new Paragraph(" "));
             * document.add(makeStatusHistoryTable(job));
             * 
             * if (this.showCompleteHistory) { document.add(new Paragraph(" "));
             * document.add(makeHistoryTable(job)); }
             */
        } catch (Exception e) {
            log.error("Exception creating pdf document", e);
            throw new VectricsException("Exception creating pdf document", e);
        }
    }

    private void makeStatusHistorySection(final Chapter chapter) throws DocumentException {
        PdfPTable infoTable = new PdfPTable(5);
        infoTable.setHorizontalAlignment(Element.ALIGN_LEFT);
        infoTable.setWidthPercentage(100);
        int infoTableWidths[] = { 80, 80, 120, 120, 120 };
        infoTable.setWidths(infoTableWidths);

        PdfPCell startDateCell = new PdfPCell(new Phrase(getPhrase("prompt.date.start"), ReportConstants.stdBoldFont));
        startDateCell.setBorderWidth(1);
        startDateCell.setBackgroundColor(ReportConstants.TABLE_LABEL_COLOR);
        infoTable.addCell(startDateCell);

        PdfPCell endDateCell = new PdfPCell(new Phrase(getPhrase("prompt.date.end"), ReportConstants.stdBoldFont));
        endDateCell.setBorderWidth(1);
        endDateCell.setBackgroundColor(ReportConstants.TABLE_LABEL_COLOR);
        infoTable.addCell(endDateCell);

        PdfPCell statusCell = new PdfPCell(new Phrase(getPhrase("prompt.job.status"), ReportConstants.stdBoldFont));
        statusCell.setBorderWidth(1);
        statusCell.setBackgroundColor(ReportConstants.TABLE_LABEL_COLOR);
        infoTable.addCell(statusCell);

        PdfPCell reasonCell = new PdfPCell(new Phrase(getPhrase("prompt.job.status.reason"),
                ReportConstants.stdBoldFont));
        reasonCell.setBorderWidth(1);
        reasonCell.setBackgroundColor(ReportConstants.TABLE_LABEL_COLOR);
        infoTable.addCell(reasonCell);

        PdfPCell personCell = new PdfPCell(new Phrase(getPhrase("prompt.job.status.person"),
                ReportConstants.stdBoldFont));
        personCell.setBorderWidth(1);
        personCell.setBackgroundColor(ReportConstants.TABLE_LABEL_COLOR);
        infoTable.addCell(personCell);

        Collection entries = DataUtils.removeVoided(job.getStatusList());
        TreeSet sorted = new TreeSet(new JobStatusDateComparator());
        sorted.addAll(entries);

        Iterator statusIter = sorted.iterator();
        while (statusIter.hasNext()) {
            JobStatus jobStatus = (JobStatus) statusIter.next();
            SimpleDateFormat dateFormat = (SimpleDateFormat) DateUtil.getFormateadorFechaHora();

            startDateCell = new PdfPCell(new Phrase(dateFormat.format(jobStatus.getDateStart()),
                    ReportConstants.stdFont));
            startDateCell.setBorderWidth(1);
            infoTable.addCell(startDateCell);

            if (jobStatus.getDateEnd() != null) {
                endDateCell = new PdfPCell(new Phrase(dateFormat.format(jobStatus.getDateEnd()),
                        ReportConstants.stdFont));
            } else {
                endDateCell = new PdfPCell(new Phrase(" ", ReportConstants.stdFont));
            }
            endDateCell.setBorderWidth(1);
            infoTable.addCell(endDateCell);

            statusCell = new PdfPCell(new Phrase(getPhrase(jobStatus.getStatusType().getDescriptionCode()),
                    ReportConstants.stdFont));
            statusCell.setBorderWidth(1);
            infoTable.addCell(statusCell);

            reasonCell = new PdfPCell(new Phrase(getPhrase(jobStatus.getStatusReasonType().getName()),
                    ReportConstants.stdFont));
            reasonCell.setBorderWidth(1);
            infoTable.addCell(reasonCell);

            personCell = new PdfPCell(new Phrase(jobStatus.getPerson().getName(), ReportConstants.stdFont));
            personCell.setBorderWidth(1);
            infoTable.addCell(personCell);
        }
        chapter.add(infoTable);
        // Blank line
        chapter.add(new Paragraph(" ", ReportConstants.stdItalicsFont));
    }

    private void makeInterviewSection(final Chapter chapter) throws DocumentException {
        // chapter.add(new Paragraph(" ", ReportConstants.heading2Font));
        // chapter.add(new Paragraph(this.getPhrase("heading.job.interviews"),
        // ReportConstants.heading1Font));
        if (job.getJobCandidates().size() == 0) {
            chapter.add(new Paragraph(getPhrase("phrase.no.interviews.found"), ReportConstants.stdItalicsFont));
        }

        // For each candidate list interviews for not just this job, but all
        // jobs.

        Iterator iter = sortCandidatesByName(job.getJobCandidates()).iterator();

        while (iter.hasNext()) {
            log.debug("Printing next candidate");
            JobCandidate jobCandidate = (JobCandidate) iter.next();
            chapter.add(new Paragraph(" ", ReportConstants.stdFont));
            Section personSection = createSection(chapter, jobCandidate.getCandidate().getPerson().getName(), 1);
            if (jobCandidate.getCandidate().getPerson().getContactInfo() != null) {
                Address homeAddress = jobCandidate.getCandidate().getPerson().getContactInfo().getHomeAddress();
                if (homeAddress != null) {
                    if (homeAddress.getAddress1() != null) {
                        personSection.add(new Paragraph(homeAddress.getAddress1(), ReportConstants.stdFont));
                    }
                    if (homeAddress.getAddress2() != null) {
                        personSection.add(new Paragraph(homeAddress.getAddress2(), ReportConstants.stdFont));
                    }

                    String cityStateZip = "";
                    if (homeAddress.getCity() != null) {
                        cityStateZip += homeAddress.getCity();
                    }
                    if (homeAddress.getState() != null) {
                        cityStateZip += ", " + homeAddress.getState();
                    }
                    if (homeAddress.getPostalCode() != null) {
                        cityStateZip += " " + homeAddress.getPostalCode();
                    }
                    if (homeAddress.getCountryCode() != null) {
                        cityStateZip += " " + homeAddress.getCountryCode();
                    }

                    personSection.add(new Paragraph(cityStateZip, ReportConstants.stdFont));
                }
                if (jobCandidate.getCandidate().getPerson().getContactInfo().getCellPhone() != null) {
                    personSection.add(new Paragraph(jobCandidate.getCandidate().getPerson().getContactInfo()
                            .getCellPhone()
                            + " (" + getPhrase("prompt.phone.cell") + ")", ReportConstants.stdFont));
                }
                if (jobCandidate.getCandidate().getPerson().getContactInfo().getHomePhone() != null) {
                    personSection.add(new Paragraph(jobCandidate.getCandidate().getPerson().getContactInfo()
                            .getCellPhone()
                            + " (" + getPhrase("prompt.phone.home") + ")", ReportConstants.stdFont));
                }
            }

            Collection interviewsForCandidate = RecruitServiceLocator.getRecruitUserService().findCandidateInterviews(
                    jobCandidate.getCandidate());

            if (interviewsForCandidate.size() == 0) {
                personSection.add(new Paragraph(getPhrase("phrase.interviews.none.for.candidate"),
                        ReportConstants.stdItalicsFont));
            }

            personSection.add(new Paragraph(" ", ReportConstants.stdItalicsFont));

            Iterator interviewIter = interviewsForCandidate.iterator();
            while (interviewIter.hasNext()) {
                Interview interview = (Interview) interviewIter.next();

                PdfPTable infoTable = new PdfPTable(2);
                infoTable.setHorizontalAlignment(Element.ALIGN_LEFT);
                infoTable.setWidthPercentage(60);
                int infoTableWidths[] = { 80, 200 };
                infoTable.setWidths(infoTableWidths);

                // Interview date
                PdfPCell captionCell = new PdfPCell(new Phrase(getPhrase("prompt.interview.date"),
                        ReportConstants.stdBoldFont));
                captionCell.setBorderWidth(0);
                infoTable.addCell(captionCell);
                PdfPCell valueCell = new PdfPCell(new Phrase(DateUtil.getFechaHoraFormateada(interview.getDateStart()),
                        ReportConstants.stdFont));
                valueCell.setBorderWidth(0);
                infoTable.addCell(valueCell);

                String description = interview.getDescription();
                if (description != null) {
                    captionCell = new PdfPCell(new Phrase(getPhrase("prompt.interview.description"),
                            ReportConstants.stdBoldFont));
                    captionCell.setBorderWidth(0);
                    infoTable.addCell(captionCell);
                    valueCell = new PdfPCell(new Phrase(description, ReportConstants.stdFont));
                    valueCell.setBorderWidth(0);
                    infoTable.addCell(valueCell);
                }

                // Job title for interview
                captionCell = new PdfPCell(new Phrase(getPhrase("prompt.job.title"), ReportConstants.stdBoldFont));
                captionCell.setBorderWidth(0);
                infoTable.addCell(captionCell);
                if (interview.getJob() != null) {
                    valueCell = new PdfPCell(new Phrase(interview.getJob().getTitle(), ReportConstants.stdFont));
                } else {
                    valueCell = new PdfPCell(new Phrase(getPhrase("phrase.not.given"), ReportConstants.stdFont));
                }
                valueCell.setBorderWidth(0);
                infoTable.addCell(valueCell);

                captionCell = new PdfPCell(new Phrase(getPhrase("prompt.interview.interviewer"),
                        ReportConstants.stdBoldFont));
                captionCell.setBorderWidth(0);
                infoTable.addCell(captionCell);
                if (interview.getLeadPerson() != null) {
                    valueCell = new PdfPCell(new Phrase(interview.getLeadPerson().getName(), ReportConstants.stdFont));
                } else {
                    valueCell = new PdfPCell(new Phrase(getPhrase("phrase.not.given"), ReportConstants.stdFont));
                }
                valueCell.setBorderWidth(0);
                infoTable.addCell(valueCell);

                captionCell = new PdfPCell(
                        new Phrase(getPhrase("prompt.interview.status"), ReportConstants.stdBoldFont));
                captionCell.setBorderWidth(0);
                infoTable.addCell(captionCell);
                valueCell = new PdfPCell(new Phrase(interview.getStatusType().getName(), ReportConstants.stdFont));
                valueCell.setBorderWidth(0);
                infoTable.addCell(valueCell);

                String result = interview.getResult();
                if (result != null) {
                    captionCell = new PdfPCell(new Phrase(getPhrase("prompt.interview.result"),
                            ReportConstants.stdBoldFont));
                    captionCell.setBorderWidth(0);
                    infoTable.addCell(captionCell);
                    valueCell = new PdfPCell(new Phrase(result, ReportConstants.stdFont));
                    valueCell.setBorderWidth(0);
                    infoTable.addCell(valueCell);
                }

                String notes = interview.getNotes();
                if (notes != null) {
                    captionCell = new PdfPCell(new Phrase(getPhrase("prompt.interview.notes"),
                            ReportConstants.stdBoldFont));
                    captionCell.setBorderWidth(0);
                    infoTable.addCell(captionCell);
                    valueCell = new PdfPCell(new Phrase(notes, ReportConstants.stdFont));
                    valueCell.setBorderWidth(0);
                    infoTable.addCell(valueCell);
                }

                personSection.add(infoTable);
                // Blank line
                personSection.add(new Paragraph(" ", ReportConstants.stdItalicsFont));

            }

        }

    }

    private PdfPTable makeSkillsTable(final SkillRatingSet ratingSet, final Job job) throws VectricsException {
        SkillRatingPdfTable skillsTable = null;
        Skill rootSkill = RecruitServiceLocator.getSkillProvider().getRootSkill();

        skillsTable = new SkillRatingPdfTable("phrase.job.skills.required", getLocale());
        skillsTable.initialize(rootSkill, ratingSet, 0);
        return skillsTable;

    }

    private PdfPTable makeHistoryTable(final Job job) throws VectricsException {
        PdfPTable historyTable = new PdfPTable(4);
        historyTable.setWidthPercentage(100);
        historyTable.setHorizontalAlignment(Element.ALIGN_LEFT);
        int headerwidths[] = { 50, 60, 80, 130 };
        try {
            historyTable.setWidths(headerwidths);
        } catch (DocumentException de) {
            log.error("DocumentException while setting history table widths", de);
            throw new VectricsException("DocumentException while setting history table widths", de);
        }
        // historyTable.setWidth(100);

        PdfPCell hdrCell = new PdfPCell(new Phrase(getPhrase("heading.transaction.history"), FontFactory.getFont(
                FontFactory.HELVETICA, 10, Font.BOLD)));
        hdrCell.setPaddingBottom(3);
        hdrCell.setColspan(4);
        hdrCell.setBackgroundColor(ReportConstants.TABLE_LABEL_COLOR);
        historyTable.addCell(hdrCell);

        hdrCell = new PdfPCell(new Phrase(getPhrase("prompt.job.date.posted"), ReportConstants.stdBoldFont));
        hdrCell.setBackgroundColor(ReportConstants.TABLE_HEAD_COLOR);
        historyTable.addCell(hdrCell);
        hdrCell = new PdfPCell(new Phrase(getPhrase("prompt.person.name"), ReportConstants.stdBoldFont));
        hdrCell.setBackgroundColor(ReportConstants.TABLE_HEAD_COLOR);
        historyTable.addCell(hdrCell);
        hdrCell = new PdfPCell(new Phrase(getPhrase("prompt.transaction.action"), ReportConstants.stdBoldFont));
        hdrCell.setBackgroundColor(ReportConstants.TABLE_HEAD_COLOR);
        historyTable.addCell(hdrCell);
        hdrCell = new PdfPCell(new Phrase(getPhrase("prompt.transaction.description"), ReportConstants.stdBoldFont));
        hdrCell.setBackgroundColor(ReportConstants.TABLE_HEAD_COLOR);
        historyTable.addCell(hdrCell);

        // this is the end of the table header
        historyTable.setHeaderRows(2);

        Collection entries = HistoryProvider.getInstance().findObjectHistoryEntries(Job.OBJECT_TYPE,
                job.getId().toString());
        Iterator iter = entries.iterator();

        while (iter.hasNext()) {
            log.debug("Printing next job history entry");
            Activity history = (Activity) iter.next();

            historyTable.addCell(ReportUtil.createPhrase(historyDateFormat.format(history.getDate()),
                    ReportConstants.stdFont));
            historyTable.addCell(ReportUtil.createPhrase(history.getPerson().getName(), ReportConstants.stdFont));
            historyTable.addCell(ReportUtil.createPhrase(history.getActivityType().getDescription(),
                    ReportConstants.stdFont));
            historyTable.addCell(ReportUtil.createPhrase(history.getDescription(), ReportConstants.stdFont));
        }
        return historyTable;
    }

    /*
     * private PdfPTable makeStatusHistoryTable(Job job) throws
     * VectricsException { PdfPTable historyTable = new PdfPTable(3);
     * historyTable.setWidthPercentage(100);
     * historyTable.setHorizontalAlignment(Element.ALIGN_LEFT); int
     * headerwidths[] = {90, 90, 130}; try {
     * historyTable.setWidths(headerwidths); } catch (DocumentException de) {
     * log.error("DocumentException while setting history table widths", de);
     * throw new
     * VectricsException("DocumentException while setting history table widths",
     * de); } //historyTable.setWidth(100);
     * 
     * PdfPCell hdrCell = new PdfPCell(new
     * Phrase(this.getPhrase("heading.transaction.history"),
     * FontFactory.getFont(FontFactory.HELVETICA, 10, Font.BOLD)));
     * hdrCell.setPaddingBottom(3); hdrCell.setColspan(3);
     * hdrCell.setBackgroundColor(ReportConstants.TABLE_LABEL_COLOR);
     * historyTable.addCell(hdrCell);
     * 
     * hdrCell = new PdfPCell(new
     * Phrase(this.getPhrase("prompt.job.status.date"),
     * ReportConstants.stdBoldFont));
     * hdrCell.setBackgroundColor(ReportConstants.TABLE_HEAD_COLOR);
     * historyTable.addCell(hdrCell); hdrCell = new PdfPCell(new
     * Phrase(this.getPhrase("prompt.person.name"),
     * ReportConstants.stdBoldFont));
     * hdrCell.setBackgroundColor(ReportConstants.TABLE_HEAD_COLOR);
     * historyTable.addCell(hdrCell); hdrCell = new PdfPCell(new
     * Phrase(this.getPhrase("prompt.job.status"),
     * ReportConstants.stdBoldFont));
     * hdrCell.setBackgroundColor(ReportConstants.TABLE_HEAD_COLOR);
     * historyTable.addCell(hdrCell);
     * 
     * 
     * // this is the end of the table header historyTable.setHeaderRows(2);
     * 
     * Collection entries = DataUtils.removeVoided(job.getStatusList()); TreeSet
     * sorted = new TreeSet(new JobStatusDateComparator());
     * sorted.addAll(entries);
     * 
     * Iterator iter = sorted.iterator();
     * 
     * while (iter.hasNext()) { log.debug("Printing next status history entry");
     * JobStatus status = (JobStatus)iter.next();
     * 
     * historyTable.addCell(ReportUtil.createPhrase(CoreServiceLocator.getDateFormat
     * (
     * ).getDateFormatRoundToMinute(this.getLocale()).format(status.getDateStart
     * ()), ReportConstants.stdFont));
     * historyTable.addCell(ReportUtil.createPhrase
     * (status.getPerson().getName(), ReportConstants.stdFont));
     * historyTable.addCell
     * (ReportUtil.createPhrase(status.getStatusType().getDescription
     * (this.getLocale()), ReportConstants.stdFont)); } return(historyTable); }
     */

    private PdfPTable makeCandidateTable(final Job job) throws VectricsException {
        PdfPTable candidateTable = new PdfPTable(4);
        candidateTable.setWidthPercentage(100);
        candidateTable.setHorizontalAlignment(Element.ALIGN_LEFT);

        int headerwidths[] = { 100, 60, 80, 130 };
        try {
            candidateTable.setWidths(headerwidths);
        } catch (DocumentException de) {
            log.error("DocumentException while setting history table widths", de);
            throw new VectricsException("DocumentException while setting history table widths", de);
        }
        // candidateTable.setWidth(100);

        PdfPCell hdrCell = new PdfPCell(new Phrase(getPhrase("heading.job.candidates"), FontFactory.getFont(
                FontFactory.HELVETICA, 10, Font.BOLD)));
        hdrCell.setPaddingBottom(3);
        hdrCell.setColspan(4);
        hdrCell.setBackgroundColor(ReportConstants.TABLE_LABEL_COLOR);
        candidateTable.addCell(hdrCell);

        hdrCell = new PdfPCell(new Phrase(getPhrase("prompt.job.candidate"), ReportConstants.stdBoldFont));
        hdrCell.setBackgroundColor(ReportConstants.TABLE_HEAD_COLOR);
        candidateTable.addCell(hdrCell);

        hdrCell = new PdfPCell(new Phrase(getPhrase("prompt.job.candidate.date.added"), ReportConstants.stdBoldFont));
        hdrCell.setBackgroundColor(ReportConstants.TABLE_HEAD_COLOR);
        candidateTable.addCell(hdrCell);

        hdrCell = new PdfPCell(new Phrase(getPhrase("prompt.job.candidate.status"), ReportConstants.stdBoldFont));
        hdrCell.setBackgroundColor(ReportConstants.TABLE_HEAD_COLOR);
        candidateTable.addCell(hdrCell);

        hdrCell = new PdfPCell(new Phrase(getPhrase("prompt.job.candidate.notes"), ReportConstants.stdBoldFont));
        hdrCell.setBackgroundColor(ReportConstants.TABLE_HEAD_COLOR);
        candidateTable.addCell(hdrCell);

        // this is the end of the table header
        candidateTable.setHeaderRows(2);
        Collection jobCandidates = sortCandidatesByName(job.getJobCandidates());

        Iterator iter = jobCandidates.iterator();
        while (iter.hasNext()) {
            log.debug("Printing next candidate");
            JobCandidate jobCandidate = (JobCandidate) iter.next();
            CandidateInfo candidate = jobCandidate.getCandidate();
            log.debug("Printing user name");
            candidateTable.addCell(ReportUtil.createPhrase(candidate.getPerson().getName(), ReportConstants.stdFont));
            log.debug("Printing date");
            candidateTable.addCell(ReportUtil.createPhrase(historyDateFormat.format(jobCandidate.getDateAdded()),
                    ReportConstants.stdFont));
            log.debug("Printing active");
            candidateTable.addCell(ReportUtil.createPhrase(""
                    + jobCandidate.getCurrentStatus().getStatusType().getDescription(), ReportConstants.stdFont));
            log.debug("Printing note");
            String notes = "";
            if (jobCandidate.getNote() != null) {
                notes = jobCandidate.getNote();
            }

            candidateTable.addCell(ReportUtil.createPhrase(notes, ReportConstants.stdFont));
            log.debug("Done printing candidate");
        }
        return candidateTable;
    }

    private PdfPTable makeCandidateStatusTable(final Job job) throws VectricsException {
        PdfPTable historyTable = new PdfPTable(3);
        historyTable.setWidthPercentage(100);
        historyTable.setHorizontalAlignment(Element.ALIGN_LEFT);
        int headerwidths[] = { 90, 90, 130 };
        try {
            historyTable.setWidths(headerwidths);
        } catch (DocumentException de) {
            log.error("DocumentException while setting history table widths", de);
            throw new VectricsException("DocumentException while setting history table widths", de);
        }
        // historyTable.setWidth(100);

        PdfPCell hdrCell = new PdfPCell(new Phrase(getPhrase("heading.transaction.history"), FontFactory.getFont(
                FontFactory.HELVETICA, 10, Font.BOLD)));
        hdrCell.setPaddingBottom(3);
        hdrCell.setColspan(3);
        hdrCell.setBackgroundColor(ReportConstants.TABLE_LABEL_COLOR);
        historyTable.addCell(hdrCell);

        hdrCell = new PdfPCell(new Phrase(getPhrase("prompt.job.status.date"), ReportConstants.stdBoldFont));
        hdrCell.setBackgroundColor(ReportConstants.TABLE_HEAD_COLOR);
        historyTable.addCell(hdrCell);
        hdrCell = new PdfPCell(new Phrase(getPhrase("prompt.person.name"), ReportConstants.stdBoldFont));
        hdrCell.setBackgroundColor(ReportConstants.TABLE_HEAD_COLOR);
        historyTable.addCell(hdrCell);
        hdrCell = new PdfPCell(new Phrase(getPhrase("prompt.job.status"), ReportConstants.stdBoldFont));
        hdrCell.setBackgroundColor(ReportConstants.TABLE_HEAD_COLOR);
        historyTable.addCell(hdrCell);

        // this is the end of the table header
        historyTable.setHeaderRows(2);

        Collection entries = DataUtils.removeVoided(job.getStatusList());
        TreeSet sorted = new TreeSet(new JobStatusDateComparator());
        sorted.addAll(entries);

        Iterator iter = sorted.iterator();

        while (iter.hasNext()) {
            log.debug("Printing next status history entry");
            JobStatus status = (JobStatus) iter.next();

            historyTable.addCell(ReportUtil.createPhrase(
                    CoreServiceLocator.getDateFormat().getDateFormatRoundToMinute(getLocale())
                            .format(status.getDateStart()), ReportConstants.stdFont));
            historyTable.addCell(ReportUtil.createPhrase(status.getPerson().getName(), ReportConstants.stdFont));
            historyTable.addCell(ReportUtil.createPhrase(status.getStatusType().getDescription(getLocale()),
                    ReportConstants.stdFont));
        }
        return historyTable;
    }

    protected Collection sortCandidatesByName(final Collection candidates) {
        TreeMap map = new TreeMap();
        Iterator iter = candidates.iterator();
        while (iter.hasNext()) {
            JobCandidate jobCandidate = (JobCandidate) iter.next();
            map.put(jobCandidate.getCandidate().getPerson().getLastName() + ","
                    + jobCandidate.getCandidate().getPerson().getFirstName(), jobCandidate);
        }
        return map.values();
    }

    public Long getJobId() {
        return jobId;
    }

    public void setJobId(final Long jobId) {
        this.jobId = jobId;
    }
}
